/* eslint-disable vue/no-setup-props-destructure */
import type { mapViewPropsType, mapViewStateType } from './typings'
import { defineComponent, onMounted, reactive, watch, shallowRef, ref } from 'vue'
import { useStore } from 'vuex'
import { ElLoading } from 'element-plus'
import {
  isPlainObject
  // cloneDeep
} from 'lodash'
import useAMap from '~/hooks/useAMap'
import useVuexGetters from '~/hooks/useVuexGetters'
import lampost from '~/assets/lightPoleOn.png'
import amapIconRef from '~/assets/ic_asset_survey_mini2.png'

export default defineComponent({
  name: 'MapView',
  props: ['id', 'clickon', 'marker'],
  emits: [
    'changeAddress',
    'clickMarker',
    'changePatterMarkerInfoView',
    'changePatterMarkerInfoPosition'
  ],
  setup(props: mapViewPropsType, { emit, expose }) {
    const store = useStore()
    const mapDomRef = ref()
    const { id = 'container' } = props
    const state = reactive<mapViewStateType>({
      currentMarker: undefined,
      currentMarkerShadow: undefined, // 阴影
      radius: 0,
      count: 0
    })
    // 获取租户设置的坐标
    const getCurrentTenant = useVuexGetters('user', ['userAddressInfo'])
    const satellite = shallowRef()
    const [mapRef, aMapRef] = useAMap(
      id,
      {
        center: [
          getCurrentTenant.userAddressInfo.value.lon,
          getCurrentTenant.userAddressInfo.value.lat
        ],
        zoom: 11
      },
      initAMap
    )

    watch(
      () => props.marker,
      () => {
        if (state.currentMarker && props.marker) {
          // const element = cloneDeep(props.marker)
          mapRef.value.setCenter([props.marker!.lng, props.marker!.lat])
          // state.currentMarker.setPosition([element.lng, element.lat])
          // state.currentMarkerShadow!.setCenter([element.lng, element.lat])
          // handleCurrentMarkerAddressList(element.lng, element.lat)
        } else if (!state.currentMarker && props.marker && mapRef.value) {
          handleAddAMapMarker(props.marker!.lng, props.marker!.lat, props.marker)
        }
      },
      { deep: true }
    )

    onMounted(() => {
      store.dispatch('user/GetCurrentTenant') // 获取租户设置的坐标
    })

    const loading = ElLoading.service({
      target: `#${id}`,
      lock: true,
      text: '加载中'
    })

    // 添加marker点击事件 将储存的值发送给父元素
    // const handleClickMarkerCallback = (e: { target: mapViewStateType['currentMarker'] }) => {
    //   emit('clickMarker', e?.target!?.getExtData?.())
    // }

    // 拖拽 移动标记点时 更新标记点的阴影位置
    // const handleDraggingMarkerCallback = () => {
    //   const markerPosition = state.currentMarker!.getPosition()
    //   state.currentMarkerShadow!.setCenter([markerPosition?.lng, markerPosition?.lat])
    // }

    // 拖拽 移动结束后 标记点并查询地址
    const handleDragMarkerCallback = () => {
      const markerPosition = state.currentMarker!.getPosition()

      mapRef.value.setCenter([markerPosition.lng, markerPosition.lat], true)
      // state.currentMarkerShadow!.setCenter([markerPosition.lng, markerPosition.lat])
      handleCurrentMarkerAddressList(markerPosition.lng, markerPosition.lat)
    }

    // 清除标记点
    const handleClearAMapMarker = () => {
      mapRef.value.clearMap()
      state.currentMarker = undefined
      state.currentMarkerShadow = undefined
    }

    // 添加标点
    const handleAddAMapMarker = (
      lng: number,
      lat: number,
      item?: mapViewStateType['currentMarker']
    ) => {
      if (state.currentMarker) {
        handleClearAMapMarker()
      }
      const icon = new aMapRef.value.Icon({
        size: new aMapRef.value.Size(28, 28),
        imageSize: new aMapRef.value.Size(28, 28),
        image: amapIconRef
      })
      const marker = new aMapRef.value.Marker({
        icon,
        position: [lng, lat],
        offset: [-12, -22],
        // zooms: [2, 18],
        extData: item || {},
        draggable: true // 可拖拽
      })
      // .setExtDate(item || {})
      // 阴影
      // const markerShadow = new aMapRef.value.CircleMarker({
      //   center: [lng, lat],
      //   radius: 50,
      //   fillColor: '#FFBBBB',
      //   fillOpacity: 0.3,
      //   strokeOpacity: 0
      // })
      state.currentMarker = marker
      // state.currentMarkerShadow = markerShadow // 阴影
      mapRef.value.add(marker)
      // mapRef.value.add(markerShadow) // 阴影
      mapRef.value.setFitView(null, false, [60, 60, 60, 60], 18)
      // marker.on('click', handleClickMarkerCallback)
      // marker.on('dragging', handleDraggingMarkerCallback) // 拖拽过程中
      marker.on('dragend', handleDragMarkerCallback) // 拖拽结束
      handleCurrentMarkerAddressList(lng, lat)
    }

    // 单击地图事件回调
    const handleClickAMapCallback = (mapsEvent: { lnglat: { lng: number; lat: number } }) => {
      const {
        lnglat: { lng, lat }
      } = mapsEvent
      if (state.currentMarker) return // 只有新增的可打点一次, 此外均不可打点, 所以这句暂加上
      handleAddAMapMarker(lng, lat)
    }

    const handleCurrentMarkerAddressList = (lng: number, lat: number) => {
      aMapRef.value.plugin(['AMap.Geocoder'], () => {
        const geocoder = new aMapRef.value.Geocoder({
          radius: 1000, // 以已知坐标为中心点，radius为半径，返回范围内兴趣点和道路信息
          extensions: 'all' // 返回地址描述以及附近兴趣点和道路信息，默认“base”
        })
        geocoder.getAddress(
          new aMapRef.value.LngLat(lng, lat),
          (
            status: string,
            result: { info: string; regeocode: { formattedAddress: string; addressComponent: any } }
          ) => {
            if (status === 'complete' && result.info === 'OK') {
              const defectAddress = result.regeocode.formattedAddress
              const addressComponent = result.regeocode.addressComponent
              const params = {
                latitude: lat,
                longitude: lng,
                defectAddress,
                region: `${addressComponent.province}-${addressComponent.city}-${addressComponent.district}`
              }
              emit('changeAddress', params)
            } else {
              emit('changeAddress', [])
            }
          }
        )
      })
    }

    // 根据props.markers来设置坐标点回调
    const handleSetMarkerByPropsMarkers = () => {
      if (props.marker && aMapRef.value) {
        const timer = setTimeout(() => {
          if (isPlainObject(props.marker)) {
            const item = props.marker
            if (item?.lng) {
              handleAddAMapMarker(
                (item as Record<string, any>)?.lng,
                (item as Record<string, any>)?.lat,
                item as any
              )
            }
          }
          clearTimeout(timer)
        }, 0)
      }
    }

    //  卫星地图展示切换
    const satelliteChangingOver = (value: boolean) => {
      if (value) {
        mapRef.value.removeLayer(satellite.value)
      } else {
        mapRef.value.addLayer(satellite.value)
      }
    }

    //  画圆
    const circle = shallowRef()
    const drawCircle = (radius: number, center: any) => {
      if (circle.value) {
        mapRef.value.remove(circle.value)
      }
      circle.value = new aMapRef.value.Circle({
        center: new aMapRef.value.LngLat(center[0], center[1]),
        radius,
        borderWeight: 2,
        strokeOpacity: 0,
        strokeDasharray: [10, 10],
        fillColor: '#ee2200',
        fillOpacity: 0.2
      })
      mapRef.value.add(circle.value)
    }

    //  周边灯杆 圆
    const onAmbitusLamp = async () => {
      const res = await store.dispatch('base/GetLampPostByscope', {
        lat: props.marker?.lat,
        lon: props.marker?.lng
      })
      if (res.code === 200) {
        appendixLamppostDraw(res?.data)
      }
      const res1 = await store.dispatch('base/GetLampPostScope')
      if (res1.code === 200) {
        state.radius = res1?.data
        drawCircle(res1?.data, [props.marker?.lng, props.marker?.lat])
      }
    }
    let drawLamppostMarker = reactive<any[]>([])
    const appendixLamppostDraw = (list: Record<string, any>[]) => {
      if (drawLamppostMarker.length > 0) {
        mapRef.value.remove(drawLamppostMarker)
        drawLamppostMarker = []
      }
      state.count = list.length
      for (let i = 0; i < list.length; i++) {
        const item = list[i]
        const markers = new aMapRef.value.Marker({
          position: item.phase.coordinates,
          content: `<div style="position: relative;left: -50%;">
              <div style="white-space: nowrap;color:red;font-weight: 500;font-size: 13px;">${item.code}</div>
            <img src="${lampost}" style="display: block;margin: auto;" width="28px" height="28px"/>
            </div>`,
          extData: item
        })
        drawLamppostMarker.push(markers)
        markers.on('click', appendixLamppostInfo)
      }
      mapRef.value.add(drawLamppostMarker)

      setTimeout(() => {
        pointInfo()
      }, 100)
    }
    //  点位信息
    const markersInfoRef = shallowRef()
    const pointInfo = () => {
      if (markersInfoRef.value) {
        mapRef.value.remove(markersInfoRef.value)
      }
      markersInfoRef.value = new aMapRef.value.Marker({
        position: [props.marker?.lng, props.marker?.lat],
        content: `
          <div style='background-color: #fff; padding: 5px; width: 90px;'>
            <div>半径：${state.radius}米</div>
            <div>灯杆：${state.count}个</div>
          </div>
        `,
        offset: [state.radius, -((state.radius || 0) / 2) + 36]
      })
      mapRef.value.add(markersInfoRef.value)
    }
    //  附近灯杆详情
    const appendixLamppostInfo = async (markerEvent: Record<string, any>) => {
      const extData = markerEvent.target.getExtData()
      const { data } = await store.dispatch('base/GetLampPostById', { id: extData.id })
      if (!data) return
      const mapClientRect = mapDomRef.value.getBoundingClientRect()
      const patternMarkerOffset = mapRef.value.lngLatToContainer(markerEvent.target!.getPosition())
      state.activePatternMarker = markerEvent.target
      const datainfo = {
        name: data.code,
        assetId: extData.id,
        moduleCode: 'lightPole',
        moduleName: '灯杆',
        infoList: [
          { type: 'text', key: '灯杆经度', value: data.lon },
          { type: 'text', key: '灯杆纬度', value: data.lat },
          { type: 'text', key: '详细地址', value: data.address }
        ]
      }
      emit(
        'changePatterMarkerInfoView',
        patternMarkerOffset.x + mapClientRect.left,
        patternMarkerOffset.y + mapClientRect.top + 18,
        'BaseStation',
        datainfo,
        []
      )
      // 给map注册拖动事件 让popover 随着拖动移动
      mapRef.value.on('mapmove', handleReplacePatterDomOffset)
      mapRef.value.on('resize', handleReplacePatterDomOffset)
      // mapRef.value.on('moveend', handleJudgeActivePatterMarkerInMap)
    }
    // 地图拖拽时的回调
    const handleReplacePatterDomOffset = () => {
      const mapClientRect = mapDomRef.value.getBoundingClientRect()
      const patternMarkerOffset = mapRef.value.lngLatToContainer(
        state.activePatternMarker!.getPosition()
      )
      if (mapClientRect && patternMarkerOffset) {
        // 将获取到的 left top 和 工区数据发送给父组建
        emit(
          'changePatterMarkerInfoPosition',
          patternMarkerOffset.x + mapClientRect.left,
          patternMarkerOffset.y + mapClientRect.top - 2
        )
      }
    }

    // 初始化map事件
    function initAMap() {
      // 放大缩小的加减按钮
      const toolBar = new aMapRef.value.ToolBar({
        position: {
          top: '20px',
          right: '20px'
        }
      })
      mapRef.value.addControl(toolBar) // 放大缩小的加减按钮
      loading.close()
      const { clickon = false } = props
      if (clickon) mapRef.value.on('click', handleClickAMapCallback)
      if (props.marker && aMapRef.value) handleSetMarkerByPropsMarkers()

      satellite.value = new aMapRef.value.TileLayer.Satellite()
      mapRef.value.addLayer(satellite.value)

      props.marker?.lng && onAmbitusLamp()
    }

    expose({
      mapRef,
      aMapRef,
      clearCurrentMarker: handleClearAMapMarker,
      setMarkersByPropsMarkers: handleSetMarkerByPropsMarkers,
      // handleClickAMapCallback // 只有新增的可打点一次, 此外均不可打点, 所以这段暂注释掉
      satelliteChangingOver,
      onAmbitusLamp,
      handleAddAMapMarker
    })
    return () => <section id={id} ref={mapDomRef}></section>
  }
})
